home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpu / tms34010 / 34010ops.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  52KB  |  1,875 lines

  1. /*** TMS34010: Portable TMS34010 emulator ************************************
  2.  
  3.     Copyright (C) Alex Pasadyn/Zsolt Vasvari 1998
  4.  
  5.     Opcodes
  6.  
  7.     Most of the opcodes were painfully tested to produce the fastest
  8.     possible code on DJGPP. If you make any changes, please test for
  9.     performace. Even a trivial change such as reordering a couple of
  10.     lines can have a change in performance.
  11.  
  12.     Most games seem to be especially sensitive to the XY instructions,
  13.     such as ADDXY and SUBXY.
  14.  
  15. *****************************************************************************/
  16.  
  17. /* clears flags */
  18. #define CLR_V (V_FLAG = 0)
  19.  
  20. #define ZEXTEND(val,width) if (width) (val) &= ((UINT32)0xffffffff>>(32-(width)))
  21. #define SEXTEND(val,width) if (width)                                                          \
  22.                            {                                                                  \
  23.                                (val) &= ((UINT32)0xffffffff>>(32-(width)));                    \
  24.                                (val) |= (((val)&(1<<((width)-1)))?((0xffffffff)<<(width)):0); \
  25.                            }
  26.  
  27. #define SET_Z(val) (NOTZ_FLAG = (val))
  28. #define SET_N(val) (N_FLAG = SIGN(val))
  29. #define SET_NZ(val) {SET_Z(val); SET_N(NOTZ_FLAG);}
  30. #define SET_V_SUB(a,b,r) (V_FLAG = SIGN( ((a)^(b))&((a)^(r))))
  31. #define SET_V_ADD(a,b,r) (V_FLAG = SIGN(~((a)^(b))&((a)^(r))))
  32. #define SET_C_SUB(a,b)  (C_FLAG = (((UINT32)  (b)) >((UINT32)(a))))
  33. #define SET_C_ADD(a,b)  (C_FLAG = (((UINT32)(~(a)))<((UINT32)(b))))
  34. #define SET_NZV_SUB(a,b,r)   {SET_NZ(r);SET_V_SUB(a,b,r);}
  35. #define SET_NZCV_SUB(a,b,r)  {SET_NZV_SUB(a,b,r);SET_C_SUB(a,b);}
  36. #define SET_NZCV_ADD(a,b,r)  {SET_NZ(r);SET_V_ADD(a,b,r);SET_C_ADD(a,b);}
  37.  
  38. #define XYTOL(val) ((((INT32)((UINT16)(val.y) )<<state.xytolshiftcount1) |    \
  39.                     (((INT32)((UINT16)(val.x)))<<state.xytolshiftcount2)) + OFFSET)
  40.  
  41.  
  42. #define COUNT_CYCLES(x)    tms34010_ICount -= x
  43. #define COUNT_UNKNOWN_CYCLES(x) COUNT_CYCLES(x)
  44.  
  45.  
  46. static void unimpl(void)
  47. {
  48.     PUSH(PC);
  49.     PUSH(GET_ST());
  50.     RESET_ST();
  51.     PC = RLONG(0xfffffc20);
  52.       COUNT_UNKNOWN_CYCLES(16);
  53.  
  54.     /* extra check to prevent bad things */
  55.     if (PC == 0 || opcode_table[cpu_readop16(TOBYTE(PC)) >> 4] == unimpl)
  56.     {
  57.         cpu_set_halt_line(cpu_getactivecpu(),ASSERT_LINE);
  58. #if MAME_DEBUG
  59.         {
  60.             extern int debug_key_pressed;
  61.             debug_key_pressed = 1;
  62.         }
  63. #endif
  64.     }
  65. }
  66.  
  67. #define ADD_XY(R)                                \
  68. {                                                \
  69.     XY res;                                        \
  70.     XY  a =  R##REG_XY(R##SRCREG);                \
  71.     XY *b = &R##REG_XY(R##DSTREG);                \
  72.     res.x = b->x + a.x;                            \
  73.        N_FLAG = !res.x;                            \
  74.        V_FLAG = res.x & 0x8000;                    \
  75.     res.y = b->y + a.y;                            \
  76.     NOTZ_FLAG = res.y;                            \
  77.        C_FLAG = res.y & 0x8000;                    \
  78.       *b = res;                                    \
  79.       COUNT_CYCLES(1);                            \
  80. }
  81. static void add_xy_a(void) { ADD_XY(A); }
  82. static void add_xy_b(void) { ADD_XY(B); }
  83.  
  84. #define SUB_XY(R)                                \
  85. {                                                \
  86.     XY  a =  R##REG_XY(R##SRCREG);                \
  87.     XY *b = &R##REG_XY(R##DSTREG);                \
  88.        N_FLAG = (a.x == b->x);                    \
  89.        V_FLAG = (a.x >  b->x);                    \
  90.        C_FLAG = (a.y >  b->y);                    \
  91.     NOTZ_FLAG = (a.y != b->y);                    \
  92.     b->x -= a.x;                                \
  93.     b->y -= a.y;                                \
  94.       COUNT_CYCLES(1);                            \
  95. }
  96. static void sub_xy_a(void) { SUB_XY(A); }
  97. static void sub_xy_b(void) { SUB_XY(B); }
  98.  
  99. #define CMP_XY(R)                                \
  100. {                                                \
  101.     INT16 res;                                    \
  102.     XY a = R##REG_XY(R##DSTREG);                \
  103.     XY b = R##REG_XY(R##SRCREG);                \
  104.     res = a.x-b.x;                                \
  105.        N_FLAG = !res;                            \
  106.        V_FLAG = (res & 0x8000);                    \
  107.     res = a.y-b.y;                                \
  108.     NOTZ_FLAG =  res;                            \
  109.        C_FLAG = (res & 0x8000);                    \
  110.       COUNT_CYCLES(1);                            \
  111. }
  112. static void cmp_xy_a(void) { CMP_XY(A); }
  113. static void cmp_xy_b(void) { CMP_XY(B); }
  114.  
  115. #define CPW(R)                                    \
  116. {                                                \
  117.     INT32 res = 0;                                \
  118.     INT16 x = R##REG_X(R##SRCREG);                \
  119.     INT16 y = R##REG_Y(R##SRCREG);                \
  120.                                                 \
  121.     res |= ((WSTART_X > x) ? 0x20  : 0);        \
  122.     res |= ((x > WEND_X)   ? 0x40  : 0);        \
  123.     res |= ((WSTART_Y > y) ? 0x80  : 0);        \
  124.     res |= ((y > WEND_Y)   ? 0x100 : 0);        \
  125.     R##REG(R##DSTREG) = V_FLAG = res;            \
  126.       COUNT_CYCLES(1);                            \
  127. }
  128. static void cpw_a(void) { CPW(A); }
  129. static void cpw_b(void) { CPW(B); }
  130.  
  131. #define CVXYL(R)                                    \
  132. {                                                    \
  133.     R##REG(R##DSTREG) = XYTOL(R##REG_XY(R##SRCREG));\
  134.       COUNT_CYCLES(3);                                \
  135. }
  136. static void cvxyl_a(void) { CVXYL(A); }
  137. static void cvxyl_b(void) { CVXYL(B); }
  138.  
  139. #define MOVX(R)                                        \
  140. {                                                    \
  141.     R##REG(R##DSTREG) = (R##REG(R##DSTREG) & 0xffff0000) | (UINT16)R##REG(R##SRCREG);    \
  142.       COUNT_CYCLES(1);                                                                    \
  143. }
  144. static void movx_a(void) { MOVX(A); }
  145. static void movx_b(void) { MOVX(B); }
  146.  
  147. #define MOVY(R)                                        \
  148. {                                                    \
  149.     R##REG(R##DSTREG) = (R##REG(R##SRCREG) & 0xffff0000) | (UINT16)R##REG(R##DSTREG);    \
  150.       COUNT_CYCLES(1);                                                                    \
  151. }
  152. static void movy_a(void) { MOVY(A); }
  153. static void movy_b(void) { MOVY(B); }
  154.  
  155. #define PIXT_RI(R)                                    \
  156. {                                                     \
  157.     WPIXEL(R##REG(R##DSTREG),R##REG(R##SRCREG));    \
  158.     FINISH_PIX_OP;                                    \
  159.       COUNT_UNKNOWN_CYCLES(2);                        \
  160. }
  161. static void pixt_ri_a(void) { PIXT_RI(A); }
  162. static void pixt_ri_b(void) { PIXT_RI(B); }
  163.  
  164. #define PIXT_RIXY(R)                                \
  165. {                                                    \
  166.     if (state.window_checking != 0 && state.window_checking != 3)            \
  167.     {                                                \
  168.         logerror("PIXT R,XY  %08X - Window Checking Mode %d not supported\n", PC, state.window_checking);    \
  169.     }                                                \
  170.                                                     \
  171.     if (state.window_checking != 3 ||                        \
  172.         (R##REG_X(R##DSTREG) >= WSTART_X && R##REG_X(R##DSTREG) <= WEND_X &&        \
  173.          R##REG_Y(R##DSTREG) >= WSTART_Y && R##REG_Y(R##DSTREG) <= WEND_Y))            \
  174.         WPIXEL(XYTOL(R##REG_XY(R##DSTREG)),R##REG(R##SRCREG));    \
  175.     FINISH_PIX_OP;                                    \
  176.       COUNT_UNKNOWN_CYCLES(4);                        \
  177. }
  178. static void pixt_rixy_a(void) { PIXT_RIXY(A); }
  179. static void pixt_rixy_b(void) { PIXT_RIXY(B); }
  180.  
  181. #define PIXT_IR(R)                                    \
  182. {                                                    \
  183.     R##REG(R##DSTREG) = V_FLAG = RPIXEL(R##REG(R##SRCREG));    \
  184.     FINISH_PIX_OP;                                    \
  185.     COUNT_CYCLES(4);                                \
  186. }
  187. static void pixt_ir_a(void) { PIXT_IR(A); }
  188. static void pixt_ir_b(void) { PIXT_IR(B); }
  189.  
  190. #define PIXT_II(R)                                       \
  191. {                                                    \
  192.     WPIXEL(R##REG(R##DSTREG),RPIXEL(R##REG(R##SRCREG)));    \
  193.     FINISH_PIX_OP;                                    \
  194.       COUNT_UNKNOWN_CYCLES(4);                        \
  195. }
  196. static void pixt_ii_a(void) { PIXT_II(A); }
  197. static void pixt_ii_b(void) { PIXT_II(B); }
  198.  
  199. #define PIXT_IXYR(R)                                  \
  200. {                                                    \
  201.     R##REG(R##DSTREG) = V_FLAG = RPIXEL(XYTOL(R##REG_XY(R##SRCREG)));    \
  202.     FINISH_PIX_OP;                                    \
  203.     COUNT_CYCLES(6);                                \
  204. }
  205. static void pixt_ixyr_a(void) { PIXT_IXYR(A); }
  206. static void pixt_ixyr_b(void) { PIXT_IXYR(B); }
  207.  
  208. #define PIXT_IXYIXY(R)                                                    \
  209. {                                                                    \
  210.     WPIXEL(XYTOL(R##REG_XY(R##DSTREG)),RPIXEL(XYTOL(R##REG_XY(R##SRCREG))));    \
  211.     FINISH_PIX_OP;                                                    \
  212.       COUNT_UNKNOWN_CYCLES(7);                                        \
  213. }
  214. static void pixt_ixyixy_a(void) { PIXT_IXYIXY(A); }
  215. static void pixt_ixyixy_b(void) { PIXT_IXYIXY(B); }
  216.  
  217. #define DRAV(R)                                                    \
  218. {                                                            \
  219.     if (state.window_checking)                    \
  220.     {                                                        \
  221.         logerror("DRAV  %08X - Window Checking Mode %d not supported\n", PC, state.window_checking);    \
  222.     }                                                        \
  223.                                                             \
  224.     WPIXEL(XYTOL(R##REG_XY(R##DSTREG)),COLOR1);                \
  225.                                                             \
  226.     R##REG_X(R##DSTREG) += R##REG_X(R##SRCREG);                \
  227.     R##REG_Y(R##DSTREG) += R##REG_Y(R##SRCREG);                \
  228.     FINISH_PIX_OP;                                            \
  229.       COUNT_UNKNOWN_CYCLES(4);                                \
  230. }
  231. static void drav_a(void) { DRAV(A); }
  232. static void drav_b(void) { DRAV(B); }
  233.  
  234.  
  235. /* General Instructions */
  236. #define ABS(R)                                                    \
  237. {                                                            \
  238.     INT32 *rd = &R##REG(R##DSTREG);                            \
  239.     INT32 r = 0 - *rd;                                        \
  240.     SET_NZV_SUB(0,*rd,r);                                    \
  241.     if (!N_FLAG)                                            \
  242.     {                                                        \
  243.         *rd = r;                                            \
  244.     }                                                        \
  245.     COUNT_CYCLES(1);                                        \
  246. }
  247. static void abs_a(void) { ABS(A); }
  248. static void abs_b(void) { ABS(B); }
  249.  
  250. #define ADD(R)                                                    \
  251. {                                                             \
  252.     INT32 a = R##REG(R##SRCREG);                            \
  253.     INT32 *rd = &R##REG(R##DSTREG);                            \
  254.     INT32 b = *rd;                                            \
  255.     INT32 r = *rd = a + b;                                    \
  256.     SET_NZCV_ADD(a,b,r);                                    \
  257.     COUNT_CYCLES(1);                                        \
  258. }
  259. static void add_a(void) { ADD(A); }
  260. static void add_b(void) { ADD(B); }
  261.  
  262. #define ADDC(R)                                                    \
  263. {                                                              \
  264.     /* I'm not sure to which side the carry is added to, should    */    \
  265.     /* verify it against the examples */                    \
  266.     INT32 a = R##REG(R##SRCREG) + (C_FLAG?1:0);                \
  267.     INT32 *rd = &R##REG(R##DSTREG);                            \
  268.     INT32 b = *rd;                                            \
  269.     INT32 r = *rd = a + b;                                    \
  270.     SET_NZCV_ADD(a,b,r);                                    \
  271.     COUNT_CYCLES(1);                                        \
  272. }
  273. static void addc_a(void) { ADDC(A); }
  274. static void addc_b(void) { ADDC(B); }
  275.  
  276. #define ADDI_W(R)                                                \
  277. {                                                              \
  278.     INT32 a = PARAM_WORD();                                    \
  279.     INT32 *rd = &R##REG(R##DSTREG);                            \
  280.     INT32 b = *rd;                                            \
  281.     INT32 r = *rd = a + b;                                    \
  282.     SET_NZCV_ADD(a,b,r);                                    \
  283.     COUNT_CYCLES(2);                                        \
  284. }
  285. static void addi_w_a(void) { ADDI_W(A); }
  286. static void addi_w_b(void) { ADDI_W(B); }
  287.  
  288. #define ADDI_L(R)                                                \
  289. {                                                              \
  290.     INT32 a = PARAM_LONG();                                    \
  291.     INT32 *rd = &R##REG(R##DSTREG);                            \
  292.     INT32 b = *rd;                                            \
  293.     INT32 r = *rd = a + b;                                    \
  294.     SET_NZCV_ADD(a,b,r);                                    \
  295.     COUNT_CYCLES(3);                                        \
  296. }
  297. static void addi_l_a(void) { ADDI_L(A); }
  298. static void addi_l_b(void) { ADDI_L(B); }
  299.  
  300. #define ADDK(R)                                                    \
  301. {                                                              \
  302.     INT32 r,b,*rd;                                            \
  303.     INT32 a = PARAM_K; if (!a) a = 32;                        \
  304.     rd = &R##REG(R##DSTREG);                                \
  305.     b = *rd;                                                \
  306.     r = *rd = a + b;                                        \
  307.     SET_NZCV_ADD(a,b,r);                                    \
  308.     COUNT_CYCLES(1);                                        \
  309. }
  310. static void addk_a(void) { ADDK(A); }
  311. static void addk_b(void) { ADDK(B); }
  312.  
  313. #define AND(R)                                                    \
  314. {                                                              \
  315.     INT32 *rd = &R##REG(R##DSTREG);                            \
  316.     *rd &= R##REG(R##SRCREG);                                \
  317.     SET_Z(*rd);                                                \
  318.     COUNT_CYCLES(1);                                        \
  319. }
  320. static void and_a(void) { AND(A); }
  321. static void and_b(void) { AND(B); }
  322.  
  323. #define ANDI(R)                                                    \
  324. {                                                              \
  325.     INT32 *rd = &R##REG(R##DSTREG);                            \
  326.     *rd &= ~PARAM_LONG();                                    \
  327.     SET_Z(*rd);                                                \
  328.     COUNT_CYCLES(3);                                        \
  329. }
  330. static void andi_a(void) { ANDI(A); }
  331. static void andi_b(void) { ANDI(B); }
  332.  
  333. #define ANDN(R)                                                    \
  334. {                                                              \
  335.     INT32 *rd = &R##REG(R##DSTREG);                            \
  336.     *rd &= ~R##REG(R##SRCREG);                                \
  337.     SET_Z(*rd);                                                \
  338.     COUNT_CYCLES(1);                                        \
  339. }
  340. static void andn_a(void) { ANDN(A); }
  341. static void andn_b(void) { ANDN(B); }
  342.  
  343. #define BTST_K(R)                                              \
  344. {                                                             \
  345.     SET_Z(R##REG(R##DSTREG) & (1<<(31-PARAM_K)));            \
  346.     COUNT_CYCLES(1);                                        \
  347. }
  348. static void btst_k_a(void) { BTST_K(A); }
  349. static void btst_k_b(void) { BTST_K(B); }
  350.  
  351. #define BTST_R(R)                                              \
  352. {                                                            \
  353.     SET_Z(R##REG(R##DSTREG) & (1<<(R##REG(R##SRCREG)&0x1f)));    \
  354.     COUNT_CYCLES(2);                                        \
  355. }
  356. static void btst_r_a(void) { BTST_R(A); }
  357. static void btst_r_b(void) { BTST_R(B); }
  358.  
  359. static void clrc(void)
  360. {
  361.     C_FLAG = 0;
  362.     COUNT_CYCLES(1);
  363. }
  364.  
  365. #define CMP(R)                                                      \
  366. {                                                            \
  367.     INT32 *rs = &R##REG(R##SRCREG);                            \
  368.     INT32 *rd = &R##REG(R##DSTREG);                            \
  369.     INT32 r = *rd - *rs;                                    \
  370.     SET_NZCV_SUB(*rd,*rs,r);                                \
  371.     COUNT_CYCLES(1);                                        \
  372. }
  373. static void cmp_a(void) { CMP(A); }
  374. static void cmp_b(void) { CMP(B); }
  375.  
  376. #define CMPI_W(R)                                                  \
  377. {                                                            \
  378.     INT32 r;                                                \
  379.     INT32 *rd = &R##REG(R##DSTREG);                            \
  380.     INT32 t = ~PARAM_WORD();                                \
  381.     r = *rd - t;                                            \
  382.     SET_NZCV_SUB(*rd,t,r);                                    \
  383.     COUNT_CYCLES(2);                                        \
  384. }
  385. static void cmpi_w_a(void) { CMPI_W(A); }
  386. static void cmpi_w_b(void) { CMPI_W(B); }
  387.  
  388. #define CMPI_L(R)                                                  \
  389. {                                                            \
  390.     INT32 *rd = &R##REG(R##DSTREG);                            \
  391.     INT32 t = ~PARAM_LONG();                                \
  392.     INT32 r = *rd - t;                                        \
  393.     SET_NZCV_SUB(*rd,t,r);                                    \
  394.     COUNT_CYCLES(3);                                        \
  395. }
  396. static void cmpi_l_a(void) { CMPI_L(A); }
  397. static void cmpi_l_b(void) { CMPI_L(B); }
  398.  
  399. static void dint(void)
  400. {
  401.     IE_FLAG = 0;
  402.     COUNT_CYCLES(3);
  403. }
  404.  
  405. #define DIVS(R,N)                                                  \
  406. {                                                            \
  407.     INT32 *rs  = &R##REG(R##SRCREG);                        \
  408.     INT32 *rd1 = &R##REG(R##DSTREG);                        \
  409.     V_FLAG = N_FLAG = 0;                                    \
  410.     NOTZ_FLAG = 1;                                            \
  411.     if (!(R##DSTREG & (1*N)))                                \
  412.     {                                                        \
  413.         if (!*rs)                                            \
  414.         {                                                    \
  415.             V_FLAG = 0;                                        \
  416.         }                                                    \
  417.         else                                                \
  418.         {                                                    \
  419.             INT32 *rd2 = &R##REG(R##DSTREG+N);                \
  420.             INT64 dividend  = COMBINE_64_32_32(*rd1, *rd2); \
  421.             INT64 quotient  = DIV_64_64_32(dividend, *rs);     \
  422.             INT32 remainder = MOD_32_64_32(dividend, *rs);     \
  423.             UINT32 signbits = ((quotient & 0x80000000) ? 0xffffffff : 0);     \
  424.             if (HI32_32_64(quotient) != signbits)            \
  425.             {                                                \
  426.                 V_FLAG = 0;                                    \
  427.             }                                                \
  428.             else                                            \
  429.             {                                                \
  430.                 *rd1 = quotient;                            \
  431.                 *rd2 = remainder;                            \
  432.                 SET_NZ(*rd1);                                \
  433.             }                                                \
  434.         }                                                    \
  435.         COUNT_CYCLES(40);                                    \
  436.     }                                                        \
  437.     else                                                    \
  438.     {                                                        \
  439.         if (!*rs)                                            \
  440.         {                                                    \
  441.             V_FLAG = 0;                                        \
  442.         }                                                    \
  443.         else                                                \
  444.         {                                                    \
  445.             *rd1 /= *rs;                                    \
  446.             SET_NZ(*rd1);                                    \
  447.         }                                                    \
  448.         COUNT_CYCLES(39);                                    \
  449.     }                                                        \
  450. }
  451. static void divs_a(void) { DIVS(A,1   ); }
  452. static void divs_b(void) { DIVS(B,0x10); }
  453.  
  454. #define DIVU(R,N)                                                  \
  455. {                                                              \
  456.     INT32 *rs  = &R##REG(R##SRCREG);                        \
  457.     INT32 *rd1 = &R##REG(R##DSTREG);                        \
  458.     V_FLAG = 0;                                                \
  459.     NOTZ_FLAG = 1;                                            \
  460.     if (!(R##DSTREG & (1*N)))                                \
  461.     {                                                        \
  462.         if (!*rs)                                            \
  463.         {                                                    \
  464.             V_FLAG = 0;                                        \
  465.         }                                                    \
  466.         else                                                \
  467.         {                                                    \
  468.             INT32 *rd2 = &R##REG(R##DSTREG+N);                \
  469.             UINT64 dividend  = COMBINE_U64_U32_U32(*rd1, *rd2);    \
  470.             UINT64 quotient  = DIV_U64_U64_U32(dividend, *rs);    \
  471.             UINT32 remainder = MOD_U32_U64_U32(dividend, *rs);     \
  472.             if (HI32_U32_U64(quotient) != 0)                \
  473.             {                                                \
  474.                 V_FLAG = 0;                                    \
  475.             }                                                \
  476.             else                                            \
  477.             {                                                \
  478.                 *rd1 = quotient;                            \
  479.                 *rd2 = remainder;                            \
  480.                 SET_Z(*rd1);                                \
  481.             }                                                \
  482.         }                                                    \
  483.     }                                                        \
  484.     else                                                    \
  485.     {                                                        \
  486.         if (!*rs)                                            \
  487.         {                                                    \
  488.             V_FLAG = 0;                                        \
  489.         }                                                    \
  490.         else                                                \
  491.         {                                                    \
  492.             *rd1 = (UINT32)*rd1 / (UINT32)*rs;                  \
  493.             SET_Z(*rd1);                                    \
  494.         }                                                    \
  495.     }                                                        \
  496.     COUNT_CYCLES(37);                                        \
  497. }
  498. static void divu_a(void) { DIVU(A,1   ); }
  499. static void divu_b(void) { DIVU(B,0x10); }
  500.  
  501. static void eint(void)
  502. {
  503.     IE_FLAG = 1;
  504.     check_interrupt();
  505.     COUNT_CYCLES(3);
  506. }
  507.  
  508. #define EXGF(F,R)                                                      \
  509. {                                                                \
  510.     INT32 *rd = &R##REG(R##DSTREG);                                \
  511.     UINT32 temp = (FE##F##_FLAG ? 0x20 : 0) | FW(F);            \
  512.     FE##F##_FLAG = (*rd&0x20);                                    \
  513.     FW(F) = (*rd&0x1f);                                            \
  514.     SET_FW();                                                    \
  515.     *rd = temp;                                                    \
  516.     COUNT_CYCLES(1);                                            \
  517. }
  518. static void exgf0_a(void) { EXGF(0,A); }
  519. static void exgf0_b(void) { EXGF(0,B); }
  520. static void exgf1_a(void) { EXGF(1,A); }
  521. static void exgf1_b(void) { EXGF(1,B); }
  522.  
  523. #define LMO(R)                                                          \
  524. {                                                                \
  525.     UINT32 res = 0;                                                \
  526.     UINT32 rs  = R##REG(R##SRCREG);                                \
  527.      INT32 *rd = &R##REG(R##DSTREG);                            \
  528.     SET_Z(rs);                                                    \
  529.     if (rs)                                                        \
  530.     {                                                            \
  531.         while (!(rs & 0x80000000))                                \
  532.         {                                                        \
  533.             res++;                                                \
  534.             rs <<= 1;                                            \
  535.         }                                                        \
  536.     }                                                            \
  537.     *rd = res;                                                    \
  538.     COUNT_CYCLES(1);                                            \
  539. }
  540. static void lmo_a(void) { LMO(A); }
  541. static void lmo_b(void) { LMO(B); }
  542.  
  543. #if TMS34010_FAST_STACK
  544. #define MMFM(R,N)                                                      \
  545. {                                                                \
  546.     INT32 i;                                                    \
  547.     UINT16 l = (UINT16) PARAM_WORD();                            \
  548.     COUNT_CYCLES(3);                                            \
  549.     if (R##DSTREG == 15*N)                                        \
  550.     {                                                            \
  551.         UINT32 bitaddr1 = SP;                                    \
  552.         UINT8 *bitaddr2 = STACKPTR(bitaddr1);                    \
  553.         for (i = 15; i >= 0 ; i--)                                \
  554.         {                                                        \
  555.             if (l & 0x8000)                                        \
  556.             {                                                    \
  557.                 R##REG(i*N) = READ_WORD(bitaddr2) + (READ_WORD(bitaddr2+2) << 16); \
  558.                 bitaddr1 += 0x20;                                \
  559.                 bitaddr2 += 4;                                    \
  560.                 COUNT_CYCLES(4);                                \
  561.             }                                                    \
  562.             l <<= 1;                                            \
  563.         }                                                        \
  564.         SP = bitaddr1;                                            \
  565.     }                                                            \
  566.     else                                                        \
  567.     {                                                            \
  568.         INT32 rd = R##DSTREG;                                    \
  569.         for (i = 15; i >= 0 ; i--)                                \
  570.         {                                                        \
  571.             if (l & 0x8000)                                        \
  572.             {                                                    \
  573.                 R##REG(i*N) = RLONG(R##REG(rd));                \
  574.                 R##REG(rd) += 0x20;                                \
  575.                 COUNT_CYCLES(4);                                \
  576.             }                                                    \
  577.             l <<= 1;                                            \
  578.         }                                                        \
  579.     }                                                            \
  580. }
  581. #else
  582. #define MMFM(R,N)                                                      \
  583. {                                                                \
  584.     INT32 i;                                                    \
  585.     UINT16 l = (UINT16) PARAM_WORD();                            \
  586.     COUNT_CYCLES(3);                                            \
  587.     {                                                            \
  588.         INT32 rd = R##DSTREG;                                    \
  589.         for (i = 15; i >= 0 ; i--)                                \
  590.         {                                                        \
  591.             if (l & 0x8000)                                        \
  592.             {                                                    \
  593.                 R##REG(i*N) = RLONG(R##REG(rd));                \
  594.                 R##REG(rd) += 0x20;                                \
  595.                 COUNT_CYCLES(4);                                \
  596.             }                                                    \
  597.             l <<= 1;                                            \
  598.         }                                                        \
  599.     }                                                            \
  600. }
  601. #endif
  602. static void mmfm_a(void) { MMFM(A,1   ); }
  603. static void mmfm_b(void) { MMFM(B,0x10); }
  604.  
  605. #if TMS34010_FAST_STACK
  606. #define MMTM(R,N)                                                      \
  607. {                                                                  \
  608.     UINT32 i;                                                    \
  609.     UINT16 l = (UINT16) PARAM_WORD();                            \
  610.     COUNT_CYCLES(2);                                            \
  611.     if (R##DSTREG == 15*N)                                        \
  612.     {                                                            \
  613.         UINT32 bitaddr1 = SP;                                    \
  614.         UINT8 *bitaddr2 = STACKPTR(bitaddr1);                    \
  615.         SET_N(bitaddr1^0x80000000);                                \
  616.         for (i = 0; i  < 16; i++)                                \
  617.         {                                                        \
  618.             if (l & 0x8000)                                        \
  619.             {                                                    \
  620.                 UINT32 reg = R##REG(i*N);                        \
  621.                 bitaddr1 -= 0x20;                                \
  622.                 bitaddr2 -= 4;                                     \
  623.                 WRITE_WORD(bitaddr2  , (UINT16)reg);            \
  624.                 WRITE_WORD(bitaddr2+2, reg >> 16);                \
  625.                 COUNT_CYCLES(4);                                \
  626.             }                                                    \
  627.             l <<= 1;                                            \
  628.         }                                                        \
  629.         SP = bitaddr1;                                            \
  630.     }                                                            \
  631.     else                                                        \
  632.     {                                                            \
  633.         INT32 rd = R##DSTREG;                                    \
  634.         SET_N(R##REG(rd)^0x80000000);                            \
  635.         for (i = 0; i  < 16; i++)                                \
  636.         {                                                        \
  637.             if (l & 0x8000)                                        \
  638.             {                                                    \
  639.                 R##REG(rd) -= 0x20;                                \
  640.                 WLONG(R##REG(rd),R##REG(i*N));                    \
  641.                 COUNT_CYCLES(4);                                \
  642.             }                                                    \
  643.             l <<= 1;                                            \
  644.         }                                                        \
  645.     }                                                            \
  646. }
  647. #else
  648. #define MMTM(R,N)                                                      \
  649. {                                                                  \
  650.     UINT32 i;                                                    \
  651.     UINT16 l = (UINT16) PARAM_WORD();                            \
  652.     COUNT_CYCLES(2);                                            \
  653.     {                                                            \
  654.         INT32 rd = R##DSTREG;                                    \
  655.         SET_N(R##REG(rd)^0x80000000);                            \
  656.         for (i = 0; i  < 16; i++)                                \
  657.         {                                                        \
  658.             if (l & 0x8000)                                        \
  659.             {                                                    \
  660.                 R##REG(rd) -= 0x20;                                \
  661.                 WLONG(R##REG(rd),R##REG(i*N));                    \
  662.                 COUNT_CYCLES(4);                                \
  663.             }                                                    \
  664.             l <<= 1;                                            \
  665.         }                                                        \
  666.     }                                                            \
  667. }
  668. #endif
  669. static void mmtm_a(void) { MMTM(A,1   ); }
  670. static void mmtm_b(void) { MMTM(B,0x10); }
  671.  
  672. #define MODS(R)                                                          \
  673. {                                                                  \
  674.     INT32 *rs = &R##REG(R##SRCREG);                                \
  675.     INT32 *rd = &R##REG(R##DSTREG);                                \
  676.     V_FLAG = (*rs == 0);                                        \
  677.     if (!V_FLAG)                                                \
  678.     {                                                            \
  679.         *rd %= *rs;                                                \
  680.         SET_Z(*rd);                                                \
  681.     }                                                            \
  682.     COUNT_CYCLES(40);                                            \
  683. }
  684. static void mods_a(void) { MODS(A); }
  685. static void mods_b(void) { MODS(B); }
  686.  
  687. #define MODU(R)                                                          \
  688. {                                                                  \
  689.     INT32 *rs = &R##REG(R##SRCREG);                                \
  690.     INT32 *rd = &R##REG(R##DSTREG);                                \
  691.     V_FLAG = (*rs == 0);                                        \
  692.     if (!V_FLAG)                                                \
  693.     {                                                            \
  694.         *rd = (UINT32)*rd % (UINT32)*rs;                        \
  695.         SET_Z(*rd);                                                \
  696.     }                                                            \
  697.     COUNT_CYCLES(35);                                            \
  698. }
  699. static void modu_a(void) { MODU(A); }
  700. static void modu_b(void) { MODU(B); }
  701.  
  702. #define MPYS(R,N)                                                      \
  703. {                                                                \
  704.     INT32 *rd1 = &R##REG(R##DSTREG);                            \
  705.                                                                 \
  706.     INT32 m1 = R##REG(R##SRCREG);                                \
  707.     SEXTEND(m1, FW(1));                                            \
  708.                                                                 \
  709.     if (!(R##DSTREG & (1*N)))                                    \
  710.     {                                                            \
  711.         INT64 product    = MUL_64_32_32(m1, *rd1);                \
  712.         *rd1             = HI32_32_64(product);                    \
  713.         R##REG(R##DSTREG+N) = LO32_32_64(product);                \
  714.         SET_Z(product!=0);                                        \
  715.         SET_N(*rd1);                                            \
  716.     }                                                            \
  717.     else                                                        \
  718.     {                                                            \
  719.         *rd1 *= m1;                                                \
  720.         SET_NZ(*rd1);                                            \
  721.     }                                                            \
  722.     COUNT_CYCLES(20);                                            \
  723. }
  724. static void mpys_a(void) { MPYS(A,1   ); }
  725. static void mpys_b(void) { MPYS(B,0x10); }
  726.  
  727. #define MPYU(R,N)                                                      \
  728. {                                                                  \
  729.     INT32 *rd1 = &R##REG(R##DSTREG);                            \
  730.                                                                 \
  731.     UINT32 m1 = R##REG(R##SRCREG);                                \
  732.     ZEXTEND(m1, FW(1));                                            \
  733.                                                                 \
  734.     if (!(R##DSTREG & (1*N)))                                    \
  735.     {                                                            \
  736.         UINT64 product   = MUL_U64_U32_U32(m1, *rd1);            \
  737.         *rd1             = HI32_U32_U64(product);                \
  738.         R##REG(R##DSTREG+N) = LO32_U32_U64(product);            \
  739.         SET_Z(product!=0);                                        \
  740.     }                                                            \
  741.     else                                                        \
  742.     {                                                            \
  743.         *rd1 = (UINT32)*rd1 * m1;                                \
  744.         SET_Z(*rd1);                                            \
  745.     }                                                            \
  746.     COUNT_CYCLES(21);                                            \
  747. }
  748. static void mpyu_a(void) { MPYU(A,1   ); }
  749. static void mpyu_b(void) { MPYU(B,0x10); }
  750.  
  751. #define NEG(R)                                                          \
  752. {                                                                  \
  753.     INT32 *rd = &R##REG(R##DSTREG);                                \
  754.     INT32 r = 0 - *rd;                                            \
  755.     SET_NZCV_SUB(0,*rd,r);                                        \
  756.     *rd = r;                                                    \
  757.     COUNT_CYCLES(1);                                            \
  758. }
  759. static void neg_a(void) { NEG(A); }
  760. static void neg_b(void) { NEG(B); }
  761.  
  762. #define NEGB(R)                                                          \
  763. {                                                                  \
  764.     INT32 *rd = &R##REG(R##DSTREG);                                \
  765.     INT32 t = *rd + (C_FLAG?1:0);                                \
  766.     INT32 r = 0 - t;                                            \
  767.     SET_NZCV_SUB(0,t,r);                                        \
  768.     *rd = r;                                                    \
  769.     COUNT_CYCLES(1);                                            \
  770. }
  771. static void negb_a(void) { NEGB(A); }
  772. static void negb_b(void) { NEGB(B); }
  773.  
  774. static void nop(void)
  775. {
  776.     COUNT_CYCLES(1);
  777. }
  778.  
  779. #define NOT(R)                                                          \
  780. {                                                                 \
  781.     INT32 *rd = &R##REG(R##DSTREG);                                \
  782.     *rd = ~(*rd);                                                \
  783.     SET_Z(*rd);                                                    \
  784.     COUNT_CYCLES(1);                                            \
  785. }
  786. static void not_a(void) { NOT(A); }
  787. static void not_b(void) { NOT(B); }
  788.  
  789. #define OR(R)                                                          \
  790. {                                                                  \
  791.     INT32 *rd = &R##REG(R##DSTREG);                                \
  792.     *rd |= R##REG(R##SRCREG);                                    \
  793.     SET_Z(*rd);                                                    \
  794.     COUNT_CYCLES(1);                                            \
  795. }
  796. static void or_a(void) { OR(A); }
  797. static void or_b(void) { OR(B); }
  798.  
  799. #define ORI(R)                                                          \
  800. {                                                                  \
  801.     INT32 *rd = &R##REG(R##DSTREG);                                \
  802.     *rd |= PARAM_LONG();                                        \
  803.     SET_Z(*rd);                                                    \
  804.     COUNT_CYCLES(3);                                            \
  805. }
  806. static void ori_a(void) { ORI(A); }
  807. static void ori_b(void) { ORI(B); }
  808.  
  809. static void setc(void)
  810. {
  811.     C_FLAG = 1;
  812.     COUNT_CYCLES(1);
  813. }
  814.  
  815. #define SETF(F)                                                    \
  816. {                                                                \
  817.     FE##F##_FLAG = state.op & 0x20;                                \
  818.     FW(F) = state.op & 0x1f;                                    \
  819.     SET_FW();                                                    \
  820.     COUNT_CYCLES(1+F);                                            \
  821. }
  822. static void setf0(void) { SETF(0); }
  823. static void setf1(void) { SETF(1); }
  824.  
  825. #define SEXT(F,R)                                                \
  826. {                                                                   \
  827.     INT32 *rd = &R##REG(R##DSTREG);                                \
  828.     SEXTEND(*rd,FW(F));                                            \
  829.     SET_NZ(*rd);                                                \
  830.     COUNT_CYCLES(3);                                            \
  831. }
  832. static void sext0_a(void) { SEXT(0,A); }
  833. static void sext0_b(void) { SEXT(0,B); }
  834. static void sext1_a(void) { SEXT(1,A); }
  835. static void sext1_b(void) { SEXT(1,B); }
  836.  
  837. #define RL(R,K)                                                          \
  838. {                                                                 \
  839.     INT32 *rd = &R##REG(R##DSTREG);                                \
  840.     INT32 res = *rd;                                            \
  841.     INT32 k = (K);                                                \
  842.     if (k)                                                        \
  843.     {                                                            \
  844.         res<<=(k-1);                                            \
  845.         C_FLAG = SIGN(res);                                        \
  846.         res<<=1;                                                \
  847.         res |= (((UINT32)*rd)>>((-k)&0x1f));                    \
  848.         *rd = res;                                                \
  849.     }                                                            \
  850.     else                                                        \
  851.     {                                                            \
  852.         C_FLAG = 0;                                                \
  853.     }                                                            \
  854.     SET_Z(res);                                                    \
  855.     COUNT_CYCLES(1);                                            \
  856. }
  857. static void rl_k_a(void) { RL(A,PARAM_K); }
  858. static void rl_k_b(void) { RL(B,PARAM_K); }
  859. static void rl_r_a(void) { RL(A,AREG(ASRCREG)&0x1f); }
  860. static void rl_r_b(void) { RL(B,BREG(BSRCREG)&0x1f); }
  861.  
  862. #define SLA(R,K)                                                \
  863. {                                                                 \
  864.      INT32 *rd = &R##REG(R##DSTREG);                            \
  865.     UINT32 res = *rd;                                            \
  866.      INT32 k = K;                                                \
  867.     if (k)                                                        \
  868.     {                                                            \
  869.         UINT32 mask = (0xffffffff<<(31-k))&0x7fffffff;            \
  870.         UINT32 res2 = SIGN(res) ? res^mask : res;                \
  871.         V_FLAG = (res2 & mask);                                    \
  872.                                                                 \
  873.         res<<=(k-1);                                            \
  874.         C_FLAG = SIGN(res);                                        \
  875.         res<<=1;                                                \
  876.         *rd = res;                                                \
  877.     }                                                            \
  878.     else                                                        \
  879.     {                                                            \
  880.         C_FLAG = V_FLAG = 0;                                    \
  881.     }                                                            \
  882.     SET_NZ(res);                                                \
  883.     COUNT_CYCLES(3);                                            \
  884. }
  885. static void sla_k_a(void) { SLA(A,PARAM_K); }
  886. static void sla_k_b(void) { SLA(B,PARAM_K); }
  887. static void sla_r_a(void) { SLA(A,AREG(ASRCREG)&0x1f); }
  888. static void sla_r_b(void) { SLA(B,BREG(BSRCREG)&0x1f); }
  889.  
  890. #define SLL(R,K)                                                \
  891. {                                                                 \
  892.      INT32 *rd = &R##REG(R##DSTREG);                            \
  893.     UINT32 res = *rd;                                            \
  894.      INT32 k = K;                                                \
  895.     if (k)                                                        \
  896.     {                                                            \
  897.         res<<=(k-1);                                            \
  898.         C_FLAG = SIGN(res);                                        \
  899.         res<<=1;                                                \
  900.         *rd = res;                                                \
  901.     }                                                            \
  902.     else                                                        \
  903.     {                                                            \
  904.         C_FLAG = 0;                                                \
  905.     }                                                            \
  906.     SET_Z(res);                                                    \
  907.     COUNT_CYCLES(1);                                            \
  908. }
  909. static void sll_k_a(void) { SLL(A,PARAM_K); }
  910. static void sll_k_b(void) { SLL(B,PARAM_K); }
  911. static void sll_r_a(void) { SLL(A,AREG(ASRCREG)&0x1f); }
  912. static void sll_r_b(void) { SLL(B,BREG(BSRCREG)&0x1f); }
  913.  
  914. #define SRA(R,K)                                                \
  915. {                                                                  \
  916.     INT32 *rd = &R##REG(R##DSTREG);                                \
  917.     INT32 res = *rd;                                            \
  918.     INT32 k = (-(K)) & 0x1f;                                    \
  919.     if (k)                                                        \
  920.     {                                                            \
  921.         res>>=(k-1);                                            \
  922.         C_FLAG = res & 1;                                        \
  923.         res>>=1;                                                \
  924.         *rd = res;                                                \
  925.     }                                                            \
  926.     else                                                        \
  927.     {                                                            \
  928.         C_FLAG = 0;                                                \
  929.     }                                                            \
  930.     SET_NZ(res);                                                \
  931.     COUNT_CYCLES(1);                                            \
  932. }
  933. static void sra_k_a(void) { SRA(A,PARAM_K); }
  934. static void sra_k_b(void) { SRA(B,PARAM_K); }
  935. static void sra_r_a(void) { SRA(A,AREG(ASRCREG)); }
  936. static void sra_r_b(void) { SRA(B,BREG(BSRCREG)); }
  937.  
  938. #define SRL(R,K)                                                \
  939. {                                                                  \
  940.      INT32 *rd = &R##REG(R##DSTREG);                            \
  941.     UINT32 res = *rd;                                            \
  942.      INT32 k = (-(K)) & 0x1f;                                    \
  943.     if (k)                                                        \
  944.     {                                                            \
  945.         res>>=(k-1);                                            \
  946.         C_FLAG = res & 1;                                        \
  947.         res>>=1;                                                \
  948.         *rd = res;                                                \
  949.     }                                                            \
  950.     else                                                        \
  951.     {                                                            \
  952.         C_FLAG = 0;                                                \
  953.     }                                                            \
  954.     SET_NZ(res);                                                \
  955.     COUNT_CYCLES(1);                                            \
  956. }
  957. static void srl_k_a(void) { SRL(A,PARAM_K); }
  958. static void srl_k_b(void) { SRL(B,PARAM_K); }
  959. static void srl_r_a(void) { SRL(A,AREG(ASRCREG)); }
  960. static void srl_r_b(void) { SRL(B,BREG(BSRCREG)); }
  961.  
  962. #define SUB(R)                                                          \
  963. {                                                                  \
  964.     INT32 *rs = &R##REG(R##SRCREG);                                \
  965.     INT32 *rd = &R##REG(R##DSTREG);                                \
  966.     INT32 r = *rd - *rs;                                        \
  967.     SET_NZCV_SUB(*rd,*rs,r);                                    \
  968.     *rd = r;                                                    \
  969.     COUNT_CYCLES(1);                                            \
  970. }
  971. static void sub_a(void) { SUB(A); }
  972. static void sub_b(void) { SUB(B); }
  973.  
  974. #define SUBB(R)                                                          \
  975. {                                                                  \
  976.     INT32 *rd = &R##REG(R##DSTREG);                                \
  977.     INT32 t = R##REG(R##SRCREG) + (C_FLAG?1:0);                    \
  978.     INT32 r = *rd - t;                                            \
  979.     SET_NZCV_SUB(*rd,t,r);                                        \
  980.     *rd = r;                                                    \
  981.     COUNT_CYCLES(1);                                            \
  982. }
  983. static void subb_a(void) { SUBB(A); }
  984. static void subb_b(void) { SUBB(B); }
  985.  
  986. #define SUBI_W(R)                                                      \
  987. {                                                                  \
  988.     INT32 *rd = &R##REG(R##DSTREG);                                \
  989.     INT32 r;                                                    \
  990.     INT32 t = ~PARAM_WORD();                                    \
  991.     r = *rd - t;                                                \
  992.     SET_NZCV_SUB(*rd,t,r);                                        \
  993.     *rd = r;                                                    \
  994.     COUNT_CYCLES(2);                                            \
  995. }
  996. static void subi_w_a(void) { SUBI_W(A); }
  997. static void subi_w_b(void) { SUBI_W(B); }
  998.  
  999. #define SUBI_L(R)                                                      \
  1000. {                                                                  \
  1001.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1002.     INT32 t = ~PARAM_LONG();                                    \
  1003.     INT32 r = *rd - t;                                            \
  1004.     SET_NZCV_SUB(*rd,t,r);                                        \
  1005.     *rd = r;                                                    \
  1006.     COUNT_CYCLES(3);                                            \
  1007. }
  1008. static void subi_l_a(void) { SUBI_L(A); }
  1009. static void subi_l_b(void) { SUBI_L(B); }
  1010.  
  1011. #define SUBK(R)                                                          \
  1012. {                                                                  \
  1013.     INT32 r;                                                    \
  1014.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1015.     INT32 t = PARAM_K; if (!t) t = 32;                            \
  1016.     r = *rd - t;                                                \
  1017.     SET_NZCV_SUB(*rd,t,r);                                        \
  1018.     *rd = r;                                                    \
  1019.     COUNT_CYCLES(1);                                            \
  1020. }
  1021. static void subk_a(void) { SUBK(A); }
  1022. static void subk_b(void) { SUBK(B); }
  1023.  
  1024. #define XOR(R)                                                          \
  1025. {                                                                  \
  1026.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1027.     *rd ^= R##REG(R##SRCREG);                                    \
  1028.     SET_Z(*rd);                                                    \
  1029.     COUNT_CYCLES(1);                                            \
  1030. }
  1031. static void xor_a(void) { XOR(A); }
  1032. static void xor_b(void) { XOR(B); }
  1033.  
  1034. #define XORI(R)                                                          \
  1035. {                                                                  \
  1036.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1037.     *rd ^= PARAM_LONG();                                        \
  1038.     SET_Z(*rd);                                                    \
  1039.     COUNT_CYCLES(3);                                            \
  1040. }
  1041. static void xori_a(void) { XORI(A); }
  1042. static void xori_b(void) { XORI(B); }
  1043.  
  1044. #define ZEXT(F,R)                                                \
  1045. {                                                                \
  1046.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1047.     ZEXTEND(*rd,FW(F));                                            \
  1048.     SET_Z(*rd);                                                    \
  1049.     COUNT_CYCLES(1);                                            \
  1050. }
  1051. static void zext0_a(void) { ZEXT(0,A); }
  1052. static void zext0_b(void) { ZEXT(0,B); }
  1053. static void zext1_a(void) { ZEXT(1,A); }
  1054. static void zext1_b(void) { ZEXT(1,B); }
  1055.  
  1056.  
  1057. /* Move Instructions */
  1058. #define MOVI_W(R)                                                      \
  1059. {                                                                  \
  1060.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1061.     *rd=PARAM_WORD();                                            \
  1062.     SET_NZ(*rd);                                                \
  1063.     CLR_V;                                                        \
  1064.     COUNT_CYCLES(2);                                            \
  1065. }
  1066. static void movi_w_a(void) { MOVI_W(A); }
  1067. static void movi_w_b(void) { MOVI_W(B); }
  1068.  
  1069. #define MOVI_L(R)                                                      \
  1070. {                                                                  \
  1071.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1072.     *rd=PARAM_LONG();                                            \
  1073.     SET_NZ(*rd);                                                \
  1074.     CLR_V;                                                        \
  1075.     COUNT_CYCLES(3);                                            \
  1076. }
  1077. static void movi_l_a(void) { MOVI_L(A); }
  1078. static void movi_l_b(void) { MOVI_L(B); }
  1079.  
  1080. #define MOVK(R)                                                          \
  1081. {                                                                \
  1082.     INT32 k = PARAM_K; if (!k) k = 32;                            \
  1083.     R##REG(R##DSTREG) = k;                                        \
  1084.     COUNT_CYCLES(1);                                            \
  1085. }
  1086. static void movk_a(void) { MOVK(A); }
  1087. static void movk_b(void) { MOVK(B); }
  1088.  
  1089. #define MOVB_RN(R)                                                      \
  1090. {                                                                \
  1091.     WBYTE(R##REG(R##DSTREG),R##REG(R##SRCREG));                    \
  1092.     COUNT_CYCLES(1);                                            \
  1093. }
  1094. static void movb_rn_a(void) { MOVB_RN(A); }
  1095. static void movb_rn_b(void) { MOVB_RN(B); }
  1096.  
  1097. #define MOVB_NR(R)                                                      \
  1098. {                                                                  \
  1099.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1100.     *rd = RBYTE(R##REG(R##SRCREG));                                \
  1101.     SET_NZ(*rd);                                                \
  1102.     CLR_V;                                                        \
  1103.     COUNT_CYCLES(3);                                            \
  1104. }
  1105. static void movb_nr_a(void) { MOVB_NR(A); }
  1106. static void movb_nr_b(void) { MOVB_NR(B); }
  1107.  
  1108. #define MOVB_NN(R)                                                \
  1109. {                                                                \
  1110.     WBYTE(R##REG(R##DSTREG),(UINT32)(UINT8)RBYTE(R##REG(R##SRCREG)));    \
  1111.     COUNT_CYCLES(3);                                            \
  1112. }
  1113. static void movb_nn_a(void) { MOVB_NN(A); }
  1114. static void movb_nn_b(void) { MOVB_NN(B); }
  1115.  
  1116. #define MOVB_R_NO(R)                                                  \
  1117. {                                                                  \
  1118.     INT32 o = PARAM_WORD();                                        \
  1119.     WBYTE(R##REG(R##DSTREG)+o,R##REG(R##SRCREG));                \
  1120.     COUNT_CYCLES(3);                                            \
  1121. }
  1122. static void movb_r_no_a(void) { MOVB_R_NO(A); }
  1123. static void movb_r_no_b(void) { MOVB_R_NO(B); }
  1124.  
  1125. #define MOVB_NO_R(R)                                                  \
  1126. {                                                                  \
  1127.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1128.     INT32 o = PARAM_WORD();                                        \
  1129.     *rd = RBYTE(R##REG(R##SRCREG)+o);                            \
  1130.     SET_NZ(*rd);                                                \
  1131.     CLR_V;                                                        \
  1132.     COUNT_CYCLES(5);                                            \
  1133. }
  1134. static void movb_no_r_a(void) { MOVB_NO_R(A); }
  1135. static void movb_no_r_b(void) { MOVB_NO_R(B); }
  1136.  
  1137. #define MOVB_NO_NO(R)                                                  \
  1138. {                                                                \
  1139.     INT32 o1 = PARAM_WORD();                                    \
  1140.     INT32 o2 = PARAM_WORD();                                    \
  1141.     WBYTE(R##REG(R##DSTREG)+o2,(UINT32)(UINT8)RBYTE(R##REG(R##SRCREG)+o1));    \
  1142.     COUNT_CYCLES(5);                                            \
  1143. }
  1144. static void movb_no_no_a(void) { MOVB_NO_NO(A); }
  1145. static void movb_no_no_b(void) { MOVB_NO_NO(B); }
  1146.  
  1147. #define MOVB_RA(R)                                                      \
  1148. {                                                                \
  1149.     WBYTE(PARAM_LONG(),R##REG(R##DSTREG));                        \
  1150.     COUNT_CYCLES(1);                                            \
  1151. }
  1152. static void movb_ra_a(void) { MOVB_RA(A); }
  1153. static void movb_ra_b(void) { MOVB_RA(B); }
  1154.  
  1155. #define MOVB_AR(R)                                                      \
  1156. {                                                                  \
  1157.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1158.     *rd = RBYTE(PARAM_LONG());                                    \
  1159.     SET_NZ(*rd);                                                \
  1160.     CLR_V;                                                        \
  1161.     COUNT_CYCLES(5);                                            \
  1162. }
  1163. static void movb_ar_a(void) { MOVB_AR(A); }
  1164. static void movb_ar_b(void) { MOVB_AR(B); }
  1165.  
  1166. static void movb_aa(void)
  1167. {
  1168.     UINT32 bitaddrs=PARAM_LONG();
  1169.     WBYTE(PARAM_LONG(),(UINT32)(UINT8)RBYTE(bitaddrs));
  1170.     COUNT_CYCLES(6);
  1171. }
  1172.  
  1173. #define MOVE_RR(RS,RD)                                                  \
  1174. {                                                                \
  1175.     INT32 *rd = &RD##REG(RD##DSTREG);                            \
  1176.     *rd = RS##REG(RS##SRCREG);                                    \
  1177.     SET_NZ(*rd);                                                \
  1178.     CLR_V;                                                        \
  1179.     COUNT_CYCLES(1);                                            \
  1180. }
  1181. static void move_rr_a (void) { MOVE_RR(A,A); }
  1182. static void move_rr_b (void) { MOVE_RR(B,B); }
  1183. static void move_rr_ax(void) { MOVE_RR(A,B); }
  1184. static void move_rr_bx(void) { MOVE_RR(B,A); }
  1185.  
  1186. #define MOVE_RN(F,R)                                                  \
  1187. {                                                                \
  1188.     WFIELD##F(R##REG(R##DSTREG),R##REG(R##SRCREG));                \
  1189.     COUNT_CYCLES(1);                                            \
  1190. }
  1191. static void move0_rn_a (void) { MOVE_RN(0,A); }
  1192. static void move0_rn_b (void) { MOVE_RN(0,B); }
  1193. static void move1_rn_a (void) { MOVE_RN(1,A); }
  1194. static void move1_rn_b (void) { MOVE_RN(1,B); }
  1195.  
  1196. #define MOVE_R_DN(F,R)                                                  \
  1197. {                                                                \
  1198.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1199.     *rd-=FW_INC(F);                                                \
  1200.     WFIELD##F(*rd,R##REG(R##SRCREG));                            \
  1201.     COUNT_CYCLES(2);                                            \
  1202. }
  1203. static void move0_r_dn_a (void) { MOVE_R_DN(0,A); }
  1204. static void move0_r_dn_b (void) { MOVE_R_DN(0,B); }
  1205. static void move1_r_dn_a (void) { MOVE_R_DN(1,A); }
  1206. static void move1_r_dn_b (void) { MOVE_R_DN(1,B); }
  1207.  
  1208. #define MOVE_R_NI(F,R)                                                  \
  1209. {                                                                  \
  1210.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1211.     WFIELD##F(*rd,R##REG(R##SRCREG));                            \
  1212.     *rd+=FW_INC(F);                                                \
  1213.     COUNT_CYCLES(1);                                            \
  1214. }
  1215. static void move0_r_ni_a (void) { MOVE_R_NI(0,A); }
  1216. static void move0_r_ni_b (void) { MOVE_R_NI(0,B); }
  1217. static void move1_r_ni_a (void) { MOVE_R_NI(1,A); }
  1218. static void move1_r_ni_b (void) { MOVE_R_NI(1,B); }
  1219.  
  1220. #define MOVE_NR(F,R)                                                  \
  1221. {                                                                \
  1222.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1223.     *rd = RFIELD##F(R##REG(R##SRCREG));                            \
  1224.     SET_NZ(*rd);                                                \
  1225.     CLR_V;                                                        \
  1226.     COUNT_CYCLES(3);                                            \
  1227. }
  1228. static void move0_nr_a (void) { MOVE_NR(0,A); }
  1229. static void move0_nr_b (void) { MOVE_NR(0,B); }
  1230. static void move1_nr_a (void) { MOVE_NR(1,A); }
  1231. static void move1_nr_b (void) { MOVE_NR(1,B); }
  1232.  
  1233. #define MOVE_DN_R(F,R)                                                  \
  1234. {                                                                  \
  1235.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1236.     INT32 *rs = &R##REG(R##SRCREG);                                \
  1237.     *rs-=FW_INC(F);                                                \
  1238.     *rd = RFIELD##F(*rs);                                        \
  1239.     SET_NZ(*rd);                                                \
  1240.     CLR_V;                                                        \
  1241.     COUNT_CYCLES(4);                                            \
  1242. }
  1243. static void move0_dn_r_a (void) { MOVE_DN_R(0,A); }
  1244. static void move0_dn_r_b (void) { MOVE_DN_R(0,B); }
  1245. static void move1_dn_r_a (void) { MOVE_DN_R(1,A); }
  1246. static void move1_dn_r_b (void) { MOVE_DN_R(1,B); }
  1247.  
  1248. #define MOVE_NI_R(F,R)                                                  \
  1249. {                                                                  \
  1250.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1251.     INT32 *rs = &R##REG(R##SRCREG);                                \
  1252.     INT32 data = RFIELD##F(*rs);                                \
  1253.     *rs+=FW_INC(F);                                                \
  1254.     *rd = data;                                                    \
  1255.     SET_NZ(*rd);                                                \
  1256.     CLR_V;                                                        \
  1257.     COUNT_CYCLES(3);                                            \
  1258. }
  1259. static void move0_ni_r_a (void) { MOVE_NI_R(0,A); }
  1260. static void move0_ni_r_b (void) { MOVE_NI_R(0,B); }
  1261. static void move1_ni_r_a (void) { MOVE_NI_R(1,A); }
  1262. static void move1_ni_r_b (void) { MOVE_NI_R(1,B); }
  1263.  
  1264. #define MOVE_NN(F,R)                                                  \
  1265. {                                                                  \
  1266.     WFIELD##F(R##REG(R##DSTREG),RFIELD##F(R##REG(R##SRCREG)));    \
  1267.     COUNT_CYCLES(3);                                            \
  1268. }
  1269. static void move0_nn_a (void) { MOVE_NN(0,A); }
  1270. static void move0_nn_b (void) { MOVE_NN(0,B); }
  1271. static void move1_nn_a (void) { MOVE_NN(1,A); }
  1272. static void move1_nn_b (void) { MOVE_NN(1,B); }
  1273.  
  1274. #define MOVE_DN_DN(F,R)                                                  \
  1275. {                                                                  \
  1276.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1277.     INT32 *rs = &R##REG(R##SRCREG);                                \
  1278.     INT32 data;                                                    \
  1279.     *rs-=FW_INC(F);                                                \
  1280.     data = RFIELD##F(*rs);                                        \
  1281.     *rd-=FW_INC(F);                                                \
  1282.     WFIELD##F(*rd,data);                                        \
  1283.     COUNT_CYCLES(4);                                            \
  1284. }
  1285. static void move0_dn_dn_a (void) { MOVE_DN_DN(0,A); }
  1286. static void move0_dn_dn_b (void) { MOVE_DN_DN(0,B); }
  1287. static void move1_dn_dn_a (void) { MOVE_DN_DN(1,A); }
  1288. static void move1_dn_dn_b (void) { MOVE_DN_DN(1,B); }
  1289.  
  1290. #define MOVE_NI_NI(F,R)                                                  \
  1291. {                                                                  \
  1292.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1293.     INT32 *rs = &R##REG(R##SRCREG);                                \
  1294.     INT32 data = RFIELD##F(*rs);                                \
  1295.     *rs+=FW_INC(F);                                                \
  1296.     WFIELD##F(*rd,data);                                        \
  1297.     *rd+=FW_INC(F);                                                \
  1298.     COUNT_CYCLES(4);                                            \
  1299. }
  1300. static void move0_ni_ni_a (void) { MOVE_NI_NI(0,A); }
  1301. static void move0_ni_ni_b (void) { MOVE_NI_NI(0,B); }
  1302. static void move1_ni_ni_a (void) { MOVE_NI_NI(1,A); }
  1303. static void move1_ni_ni_b (void) { MOVE_NI_NI(1,B); }
  1304.  
  1305. #define MOVE_R_NO(F,R)                                                  \
  1306. {                                                                  \
  1307.     INT32 o = PARAM_WORD();                                        \
  1308.     WFIELD##F(R##REG(R##DSTREG)+o,R##REG(R##SRCREG));            \
  1309.     COUNT_CYCLES(3);                                            \
  1310. }
  1311. static void move0_r_no_a (void) { MOVE_R_NO(0,A); }
  1312. static void move0_r_no_b (void) { MOVE_R_NO(0,B); }
  1313. static void move1_r_no_a (void) { MOVE_R_NO(1,A); }
  1314. static void move1_r_no_b (void) { MOVE_R_NO(1,B); }
  1315.  
  1316. #define MOVE_NO_R(F,R)                                                  \
  1317. {                                                                  \
  1318.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1319.     INT32 o = PARAM_WORD();                                        \
  1320.     *rd = RFIELD##F(R##REG(R##SRCREG)+o);                        \
  1321.     SET_NZ(*rd);                                                \
  1322.     CLR_V;                                                        \
  1323.     COUNT_CYCLES(5);                                            \
  1324. }
  1325. static void move0_no_r_a (void) { MOVE_NO_R(0,A); }
  1326. static void move0_no_r_b (void) { MOVE_NO_R(0,B); }
  1327. static void move1_no_r_a (void) { MOVE_NO_R(1,A); }
  1328. static void move1_no_r_b (void) { MOVE_NO_R(1,B); }
  1329.  
  1330. #define MOVE_NO_NI(F,R)                                                  \
  1331. {                                                                  \
  1332.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1333.     INT32 o = PARAM_WORD();                                        \
  1334.     INT32 data = RFIELD##F(R##REG(R##SRCREG)+o);                \
  1335.     WFIELD##F(*rd,data);                                        \
  1336.     *rd+=FW_INC(F);                                                \
  1337.     COUNT_CYCLES(5);                                            \
  1338. }
  1339. static void move0_no_ni_a (void) { MOVE_NO_NI(0,A); }
  1340. static void move0_no_ni_b (void) { MOVE_NO_NI(0,B); }
  1341. static void move1_no_ni_a (void) { MOVE_NO_NI(1,A); }
  1342. static void move1_no_ni_b (void) { MOVE_NO_NI(1,B); }
  1343.  
  1344. #define MOVE_NO_NO(F,R)                                                  \
  1345. {                                                                 \
  1346.     INT32 o1 = PARAM_WORD();                                    \
  1347.     INT32 o2 = PARAM_WORD();                                    \
  1348.     INT32 data = RFIELD##F(R##REG(R##SRCREG)+o1);                \
  1349.     WFIELD##F(R##REG(R##DSTREG)+o2,data);                        \
  1350.     COUNT_CYCLES(5);                                            \
  1351. }
  1352. static void move0_no_no_a (void) { MOVE_NO_NO(0,A); }
  1353. static void move0_no_no_b (void) { MOVE_NO_NO(0,B); }
  1354. static void move1_no_no_a (void) { MOVE_NO_NO(1,A); }
  1355. static void move1_no_no_b (void) { MOVE_NO_NO(1,B); }
  1356.  
  1357. #define MOVE_RA(F,R)                                                  \
  1358. {                                                                  \
  1359.     WFIELD##F(PARAM_LONG(),R##REG(R##DSTREG));                    \
  1360.     COUNT_CYCLES(3);                                            \
  1361. }
  1362. static void move0_ra_a (void) { MOVE_RA(0,A); }
  1363. static void move0_ra_b (void) { MOVE_RA(0,B); }
  1364. static void move1_ra_a (void) { MOVE_RA(1,A); }
  1365. static void move1_ra_b (void) { MOVE_RA(1,B); }
  1366.  
  1367. #define MOVE_AR(F,R)                                                  \
  1368. {                                                                  \
  1369.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1370.     *rd = RFIELD##F(PARAM_LONG());                                \
  1371.     SET_NZ(*rd);                                                \
  1372.     CLR_V;                                                        \
  1373.     COUNT_CYCLES(5);                                            \
  1374. }
  1375. static void move0_ar_a (void) { MOVE_AR(0,A); }
  1376. static void move0_ar_b (void) { MOVE_AR(0,B); }
  1377. static void move1_ar_a (void) { MOVE_AR(1,A); }
  1378. static void move1_ar_b (void) { MOVE_AR(1,B); }
  1379.  
  1380. #define MOVE_A_NI(F,R)                                                  \
  1381. {                                                                  \
  1382.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1383.     WFIELD##F(*rd,RFIELD##F(PARAM_LONG()));                        \
  1384.     *rd+=FW_INC(F);                                                \
  1385.     COUNT_CYCLES(5);                                            \
  1386. }
  1387. static void move0_a_ni_a (void) { MOVE_A_NI(0,A); }
  1388. static void move0_a_ni_b (void) { MOVE_A_NI(0,B); }
  1389. static void move1_a_ni_a (void) { MOVE_A_NI(1,A); }
  1390. static void move1_a_ni_b (void) { MOVE_A_NI(1,B); }
  1391.  
  1392. #define MOVE_AA(F)                                                      \
  1393. {                                                                \
  1394.     UINT32 bitaddrs=PARAM_LONG();                                \
  1395.     WFIELD##F(PARAM_LONG(),RFIELD##F(bitaddrs));                \
  1396.     COUNT_CYCLES(7);                                            \
  1397. }
  1398. static void move0_aa (void) { MOVE_AA(0); }
  1399. static void move1_aa (void) { MOVE_AA(1); }
  1400.  
  1401.  
  1402. /* Program Control and Context Switching */
  1403. #define CALL(R)                                                    \
  1404. {                                                                \
  1405.     PUSH(PC);                                                    \
  1406.     PC = R##REG(R##DSTREG);                                        \
  1407.     COUNT_CYCLES(3);                                            \
  1408. }
  1409. static void call_a (void) { CALL(A); }
  1410. static void call_b (void) { CALL(B); }
  1411.  
  1412. static void callr(void)
  1413. {
  1414.     PUSH(PC+0x10);
  1415.     PC += (PARAM_WORD_NO_INC()<<4)+0x10;
  1416.     COUNT_CYCLES(3);
  1417. }
  1418.  
  1419. static void calla(void)
  1420. {
  1421.     PUSH(PC+0x20);
  1422.     PC = PARAM_LONG_NO_INC();
  1423.     COUNT_CYCLES(4);
  1424. }
  1425.  
  1426. #define DSJ(R)                                                    \
  1427. {                                                                \
  1428.     if (--R##REG(R##DSTREG))                                    \
  1429.     {                                                            \
  1430.         PC += (PARAM_WORD_NO_INC()<<4)+0x10;                    \
  1431.         COUNT_CYCLES(3);                                        \
  1432.     }                                                            \
  1433.     else                                                        \
  1434.     {                                                            \
  1435.         SKIP_WORD;                                                \
  1436.         COUNT_CYCLES(2);                                        \
  1437.     }                                                            \
  1438. }
  1439. static void dsj_a (void) { DSJ(A); }
  1440. static void dsj_b (void) { DSJ(B); }
  1441.  
  1442. #define DSJEQ(R)                                                \
  1443. {                                                                \
  1444.     if (!NOTZ_FLAG)                                                \
  1445.     {                                                            \
  1446.         if (--R##REG(R##DSTREG))                                \
  1447.         {                                                        \
  1448.             PC += (PARAM_WORD_NO_INC()<<4)+0x10;                \
  1449.             COUNT_CYCLES(3);                                    \
  1450.         }                                                        \
  1451.         else                                                    \
  1452.         {                                                        \
  1453.             SKIP_WORD;                                            \
  1454.             COUNT_CYCLES(2);                                    \
  1455.         }                                                        \
  1456.     }                                                            \
  1457.     else                                                        \
  1458.     {                                                            \
  1459.         SKIP_WORD;                                                \
  1460.         COUNT_CYCLES(2);                                        \
  1461.     }                                                            \
  1462. }
  1463. static void dsjeq_a (void) { DSJEQ(A); }
  1464. static void dsjeq_b (void) { DSJEQ(B); }
  1465.  
  1466. #define DSJNE(R)                                                \
  1467. {                                                                \
  1468.     if (NOTZ_FLAG)                                                \
  1469.     {                                                            \
  1470.         if (--R##REG(R##DSTREG))                                \
  1471.         {                                                        \
  1472.             PC += (PARAM_WORD_NO_INC()<<4)+0x10;                \
  1473.             COUNT_CYCLES(3);                                    \
  1474.         }                                                        \
  1475.         else                                                    \
  1476.         {                                                        \
  1477.             SKIP_WORD;                                            \
  1478.             COUNT_CYCLES(2);                                    \
  1479.         }                                                        \
  1480.     }                                                            \
  1481.     else                                                        \
  1482.     {                                                            \
  1483.         SKIP_WORD;                                                \
  1484.         COUNT_CYCLES(2);                                        \
  1485.     }                                                            \
  1486. }
  1487. static void dsjne_a (void) { DSJNE(A); }
  1488. static void dsjne_b (void) { DSJNE(B); }
  1489.  
  1490. #define DSJS(R)                                                    \
  1491. {                                                                   \
  1492.     if (state.op & 0x0400)                                        \
  1493.     {                                                            \
  1494.         if (--R##REG(R##DSTREG))                                \
  1495.         {                                                        \
  1496.             PC -= ((PARAM_K)<<4);                                \
  1497.             COUNT_CYCLES(2);                                    \
  1498.         }                                                        \
  1499.         else                                                    \
  1500.             COUNT_CYCLES(3);                                    \
  1501.     }                                                            \
  1502.     else                                                        \
  1503.     {                                                            \
  1504.         if (--R##REG(R##DSTREG))                                \
  1505.         {                                                        \
  1506.             PC += ((PARAM_K)<<4);                                \
  1507.             COUNT_CYCLES(2);                                    \
  1508.         }                                                        \
  1509.         else                                                    \
  1510.             COUNT_CYCLES(3);                                    \
  1511.     }                                                            \
  1512. }
  1513. static void dsjs_a (void) { DSJS(A); }
  1514. static void dsjs_b (void) { DSJS(B); }
  1515.  
  1516. static void emu(void)
  1517. {
  1518.     /* in RUN state, this instruction is a NOP */
  1519.     COUNT_CYCLES(6);
  1520. }
  1521.  
  1522. #define EXGPC(R)                                                \
  1523. {                                                                  \
  1524.     INT32 *rd = &R##REG(R##DSTREG);                                \
  1525.     INT32 temppc = *rd;                                            \
  1526.     *rd = PC;                                                    \
  1527.     PC = temppc;                                                \
  1528.     COUNT_CYCLES(2);                                            \
  1529. }
  1530. static void exgpc_a (void) { EXGPC(A); }
  1531. static void exgpc_b (void) { EXGPC(B); }
  1532.  
  1533. #define GETPC(R)                                                \
  1534. {                                                                \
  1535.     R##REG(R##DSTREG) = PC;                                        \
  1536.     COUNT_CYCLES(1);                                            \
  1537. }
  1538. static void getpc_a (void) { GETPC(A); }
  1539. static void getpc_b (void) { GETPC(B); }
  1540.  
  1541. #define GETST(R)                                                \
  1542. {                                                                  \
  1543.     R##REG(R##DSTREG) = GET_ST();                                \
  1544.     COUNT_CYCLES(1);                                            \
  1545. }
  1546. static void getst_a (void) { GETST(A); }
  1547. static void getst_b (void) { GETST(B); }
  1548.  
  1549. #define j_xx_8(TAKE)                                              \
  1550. {                                                                   \
  1551.     if (ADSTREG)                                                \
  1552.     {                                                            \
  1553.         if (TAKE)                                                \
  1554.         {                                                        \
  1555.             PC += (PARAM_REL8 << 4);                            \
  1556.             COUNT_CYCLES(2);                                    \
  1557.         }                                                        \
  1558.         else                                                    \
  1559.             COUNT_CYCLES(1);                                    \
  1560.     }                                                            \
  1561.     else                                                        \
  1562.     {                                                            \
  1563.         if (TAKE)                                                \
  1564.         {                                                        \
  1565.             PC = PARAM_LONG_NO_INC();                            \
  1566.             COUNT_CYCLES(3);                                    \
  1567.         }                                                        \
  1568.         else                                                    \
  1569.         {                                                        \
  1570.             SKIP_LONG;                                            \
  1571.             COUNT_CYCLES(4);                                    \
  1572.         }                                                        \
  1573.     }                                                            \
  1574. }
  1575.  
  1576. #define j_xx_0(TAKE)                                            \
  1577. {                                                                \
  1578.     if (ADSTREG)                                                \
  1579.     {                                                            \
  1580.         if (TAKE)                                                \
  1581.         {                                                        \
  1582.             PC += (PARAM_REL8 << 4);                            \
  1583.             COUNT_CYCLES(2);                                    \
  1584.         }                                                        \
  1585.         else                                                    \
  1586.             COUNT_CYCLES(1);                                    \
  1587.     }                                                            \
  1588.     else                                                        \
  1589.     {                                                            \
  1590.         if (TAKE)                                                \
  1591.         {                                                        \
  1592.             PC += (PARAM_WORD_NO_INC()<<4)+0x10;                \
  1593.             COUNT_CYCLES(3);                                    \
  1594.         }                                                        \
  1595.         else                                                    \
  1596.         {                                                        \
  1597.             SKIP_WORD;                                            \
  1598.             COUNT_CYCLES(2);                                    \
  1599.         }                                                        \
  1600.     }                                                            \
  1601. }
  1602.  
  1603. #define j_xx_x(TAKE)                                            \
  1604. {                                                                \
  1605.     if (TAKE)                                                    \
  1606.     {                                                            \
  1607.         PC += (PARAM_REL8 << 4);                                \
  1608.         COUNT_CYCLES(2);                                        \
  1609.     }                                                            \
  1610.     else                                                        \
  1611.         COUNT_CYCLES(1);                                        \
  1612. }
  1613.  
  1614. static void j_UC_0(void)
  1615. {
  1616.     j_xx_0(1);
  1617. }
  1618. static void j_UC_8(void)
  1619. {
  1620.     j_xx_8(1);
  1621. }
  1622. static void j_UC_x(void)
  1623. {
  1624.     j_xx_x(1);
  1625. }
  1626. static void j_P_0(void)
  1627. {
  1628.     j_xx_0(!N_FLAG && NOTZ_FLAG);
  1629. }
  1630. static void j_P_8(void)
  1631. {
  1632.     j_xx_8(!N_FLAG && NOTZ_FLAG);
  1633. }
  1634. static void j_P_x(void)
  1635. {
  1636.     j_xx_x(!N_FLAG && NOTZ_FLAG);
  1637. }
  1638. static void j_LS_0(void)
  1639. {
  1640.     j_xx_0(C_FLAG || !NOTZ_FLAG);
  1641. }
  1642. static void j_LS_8(void)
  1643. {
  1644.     j_xx_8(C_FLAG || !NOTZ_FLAG);
  1645. }
  1646. static void j_LS_x(void)
  1647. {
  1648.     j_xx_x(C_FLAG || !NOTZ_FLAG);
  1649. }
  1650. static void j_HI_0(void)
  1651. {
  1652.     j_xx_0(!C_FLAG && NOTZ_FLAG);
  1653. }
  1654. static void j_HI_8(void)
  1655. {
  1656.     j_xx_8(!C_FLAG && NOTZ_FLAG);
  1657. }
  1658. static void j_HI_x(void)
  1659. {
  1660.     j_xx_x(!C_FLAG && NOTZ_FLAG);
  1661. }
  1662. static void j_LT_0(void)
  1663. {
  1664.     j_xx_0((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG));
  1665. }
  1666. static void j_LT_8(void)
  1667. {
  1668.     j_xx_8((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG));
  1669. }
  1670. static void j_LT_x(void)
  1671. {
  1672.     j_xx_x((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG));
  1673. }
  1674. static void j_GE_0(void)
  1675. {
  1676.     j_xx_0((N_FLAG && V_FLAG) || (!N_FLAG && !V_FLAG));
  1677. }
  1678. static void j_GE_8(void)
  1679. {
  1680.     j_xx_8((N_FLAG && V_FLAG) || (!N_FLAG && !V_FLAG));
  1681. }
  1682. static void j_GE_x(void)
  1683. {
  1684.     j_xx_x((N_FLAG && V_FLAG) || (!N_FLAG && !V_FLAG));
  1685. }
  1686. static void j_LE_0(void)
  1687. {
  1688.     j_xx_0((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG) || !NOTZ_FLAG);
  1689. }
  1690. static void j_LE_8(void)
  1691. {
  1692.     j_xx_8((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG) || !NOTZ_FLAG);
  1693. }
  1694. static void j_LE_x(void)
  1695. {
  1696.     j_xx_x((N_FLAG && !V_FLAG) || (!N_FLAG && V_FLAG) || !NOTZ_FLAG);
  1697. }
  1698. static void j_GT_0(void)
  1699. {
  1700.     j_xx_0((N_FLAG && V_FLAG && NOTZ_FLAG) || (!N_FLAG && !V_FLAG && NOTZ_FLAG));
  1701. }
  1702. static void j_GT_8(void)
  1703. {
  1704.     j_xx_8((N_FLAG && V_FLAG && NOTZ_FLAG) || (!N_FLAG && !V_FLAG && NOTZ_FLAG));
  1705. }
  1706. static void j_GT_x(void)
  1707. {
  1708.     j_xx_x((N_FLAG && V_FLAG && NOTZ_FLAG) || (!N_FLAG && !V_FLAG && NOTZ_FLAG));
  1709. }
  1710. static void j_C_0(void)
  1711. {
  1712.     j_xx_0(C_FLAG);
  1713. }
  1714. static void j_C_8(void)
  1715. {
  1716.     j_xx_8(C_FLAG);
  1717. }
  1718. static void j_C_x(void)
  1719. {
  1720.     j_xx_x(C_FLAG);
  1721. }
  1722. static void j_NC_0(void)
  1723. {
  1724.     j_xx_0(!C_FLAG);
  1725. }
  1726. static void j_NC_8(void)
  1727. {
  1728.     j_xx_8(!C_FLAG);
  1729. }
  1730. static void j_NC_x(void)
  1731. {
  1732.     j_xx_x(!C_FLAG);
  1733. }
  1734. static void j_EQ_0(void)
  1735. {
  1736.     j_xx_0(!NOTZ_FLAG);
  1737. }
  1738. static void j_EQ_8(void)
  1739. {
  1740.     j_xx_8(!NOTZ_FLAG);
  1741. }
  1742. static void j_EQ_x(void)
  1743. {
  1744.     j_xx_x(!NOTZ_FLAG);
  1745. }
  1746. static void j_NE_0(void)
  1747. {
  1748.     j_xx_0(NOTZ_FLAG);
  1749. }
  1750. static void j_NE_8(void)
  1751. {
  1752.     j_xx_8(NOTZ_FLAG);
  1753. }
  1754. static void j_NE_x(void)
  1755. {
  1756.     j_xx_x(NOTZ_FLAG);
  1757. }
  1758. static void j_V_0(void)
  1759. {
  1760.     j_xx_0(V_FLAG);
  1761. }
  1762. static void j_V_8(void)
  1763. {
  1764.     j_xx_8(V_FLAG);
  1765. }
  1766. static void j_V_x(void)
  1767. {
  1768.     j_xx_x(V_FLAG);
  1769. }
  1770. static void j_NV_0(void)
  1771. {
  1772.     j_xx_0(!V_FLAG);
  1773. }
  1774. static void j_NV_8(void)
  1775. {
  1776.     j_xx_8(!V_FLAG);
  1777. }
  1778. static void j_NV_x(void)
  1779. {
  1780.     j_xx_x(!V_FLAG);
  1781. }
  1782. static void j_N_0(void)
  1783. {
  1784.     j_xx_0(N_FLAG);
  1785. }
  1786. static void j_N_8(void)
  1787. {
  1788.     j_xx_8(N_FLAG);
  1789. }
  1790. static void j_N_x(void)
  1791. {
  1792.     j_xx_x(N_FLAG);
  1793. }
  1794. static void j_NN_0(void)
  1795. {
  1796.     j_xx_0(!N_FLAG);
  1797. }
  1798. static void j_NN_8(void)
  1799. {
  1800.     j_xx_8(!N_FLAG);
  1801. }
  1802. static void j_NN_x(void)
  1803. {
  1804.     j_xx_x(!N_FLAG);
  1805. }
  1806.  
  1807. #define JUMP(R)                                                    \
  1808. {                                                                \
  1809.     PC = R##REG(R##DSTREG);                                        \
  1810.     COUNT_CYCLES(2);                                            \
  1811. }
  1812. static void jump_a (void) { JUMP(A); }
  1813. static void jump_b (void) { JUMP(B); }
  1814.  
  1815. static void popst(void)
  1816. {
  1817.     SET_ST(POP());
  1818.     COUNT_CYCLES(8);
  1819. }
  1820.  
  1821. static void pushst(void)
  1822. {
  1823.     PUSH(GET_ST());
  1824.     COUNT_CYCLES(2);
  1825. }
  1826.  
  1827. #define PUTST(R)                                                \
  1828. {                                                                \
  1829.     SET_ST(R##REG(R##DSTREG));                                    \
  1830.     COUNT_CYCLES(3);                                            \
  1831. }
  1832. static void putst_a (void) { PUTST(A); }
  1833. static void putst_b (void) { PUTST(B); }
  1834.  
  1835. static void reti(void)
  1836. {
  1837.     INT32 st = POP();
  1838.     PC = POP();
  1839.     SET_ST(st);
  1840.     COUNT_CYCLES(11);
  1841. }
  1842.  
  1843. static void rets(void)
  1844. {
  1845.     UINT32 offs;
  1846.     PC = POP();
  1847.     offs = PARAM_N;
  1848.     if (offs)
  1849.     {
  1850.         SP+=(offs<<4);
  1851.     }
  1852.     COUNT_CYCLES(7);
  1853. }
  1854.  
  1855. #define REV(R)                                                    \
  1856. {                                                                \
  1857.     R##REG(R##DSTREG) = 0x0008;                                    \
  1858.     COUNT_CYCLES(1);                                            \
  1859. }
  1860. static void rev_a (void) { REV(A); }
  1861. static void rev_b (void) { REV(B); }
  1862.  
  1863. static void trap(void)
  1864. {
  1865.     UINT32 t = PARAM_N;
  1866.     if (t)
  1867.     {
  1868.         PUSH(PC);
  1869.         PUSH(GET_ST());
  1870.     }
  1871.     RESET_ST();
  1872.     PC = RLONG(0xffffffe0-(t<<5));
  1873.     COUNT_CYCLES(16);
  1874. }
  1875.